#!/usr/bin/env python
# -*- coding: ISO-8859-15 -*-
#
# Copyright (C) 2007 Rafael S. Gonzalez D'Leon <rafaeldleon@gmail.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA



from sshproxy.config import ConfigSection, get_config
from sshproxy.acl import ACLDB

from config import LDAPConfigSection
from ldapops import LDAPDB

from operator import itemgetter
from time import strftime

class LDAPACLConfigSection(LDAPConfigSection):
    section_id = 'acl_db.ldap'

LDAPACLConfigSection.register()


class LDAPACLDB(ACLDB, LDAPDB):
    _db_handler = 'acl_db'
    def __reginit__(self):
        self.open_db()
        ACLDB.__reginit__(self)

    def load_rules(self):
        query = '(objectClass=sshProxyAcl)'
        
        result = self.ldap_list(query)
        rules = []
        for dn, attributes in result:
            acl = attributes['sshProxyAclType'][0]
            rule = attributes['sshProxyAclRule'][0]
            if attributes.has_key('sshProxyPriority'):
                weight = int(attributes['sshProxyPriority'][0])
            else:
                weight = 0
            rules.append((acl,rule,weight))
        rules.sort(key=itemgetter(2))
        
        for acl, rule, weight in rules:
            self.add_rule(acl=acl, rule=rule.strip(), updatedb=False)

    def save_rules(self):
        pass

    def add_rule(self, acl, rule=None, index=None, updatedb=True):
        index = ACLDB.add_rule(self, acl, rule, index)
        if not updatedb:
            return index
        if index < len(self.rules[acl]):
            query = '(&(objectClass=sshProxyAcl)(sshProxyAclType=%s))' % acl
            result = self.ldap_list(query)
            if result:
                for dn, attributes in result:
                    try:
                        weight = int(attributes['sshProxyPriority'][0])
                    except:
                        weight = 0
                    if weight >= index:
                        self.ldap_update(dn,[('sshProxyPriority',str(weight+1))])
                                       
        cfg = get_config('%s.ldap' % self._db_handler)
        base_dn = cfg['base_dn']
        cn = strftime('%Y%m%d%H%M%S')
        self.ldap_add('cn=%s,'%cn+base_dn,[('objectClass',['sshProxyAcl','top']),('cn',cn),('sshProxyAclType',acl),
                                          ('sshProxyAclRule',rule),('sshProxyPriority',str(index))])
      
        return index

    def set_rule(self, acl, rule, index):
        if not ACLDB.set_rule(self, acl, rule, index):
            return False
        query = '(&(objectClass=sshProxyAcl)(sshProxyAclType=%s)(sshProxyPriority=%s))'%(acl,index)
        result = self.ldap_get(query)
        if result:
            dn,attributes = result
            modlist = [('sshProxyAclRule',rule)]
            self.ldap_update(dn,modlist)
        
        return True

    def del_rule(self, acl, index):
        if index is not None:
            query = '(&(objectClass=sshProxyAcl)(sshProxyAclType=%s)(sshProxyPriority=%s))'%(acl,index)
            result = self.ldap_get(query)
            if result:
                dn,attributes=result
                self.ldap_del(dn)
            
            
            query = '(&(objectClass=sshProxyAcl)(sshProxyAclType=%s))' % acl 
            result = self.ldap_list(query)
            if result:
                for dn, attributes in result:
                    try:
                        weight = int(attributes['sshProxyPriority'][0])
                    except:
                        weight = 0
                    if weight >= index:
                        self.ldap_update(dn,[('sshProxyPriority',str(weight-1))])
                

        return ACLDB.del_rule(self, acl, index)

